use axum::{
    body::Body,
    extract::Request,
    http::{Method, StatusCode, Uri},
    middleware::Next,
    response::Response,
};
use chrono::{DateTime, Utc};
use log::info;
use std::time::Instant;

/// 请求日志中间件
/// 记录格式类似 nginx 的访问日志：
/// [时间] "方法 路径 协议" 状态码 响应时间ms 用户代理 客户端IP
pub async fn request_logger_middleware(request: Request, next: Next) -> Response {
    let start_time = Instant::now();
    let method = request.method().clone();
    let uri = request.uri().clone();
    let version = request.version();

    // 获取用户代理
    let user_agent = request
        .headers()
        .get("user-agent")
        .and_then(|h| h.to_str().ok())
        .unwrap_or("-")
        .to_string();

    // 获取客户端IP（优先从X-Forwarded-For获取）
    let client_ip = request
        .headers()
        .get("x-forwarded-for")
        .and_then(|h| h.to_str().ok())
        .or_else(|| {
            request
                .headers()
                .get("x-real-ip")
                .and_then(|h| h.to_str().ok())
        })
        .unwrap_or("unknown")
        .to_string();

    // 执行请求处理
    let response = next.run(request).await;

    // 计算响应时间
    let duration = start_time.elapsed();
    let duration_ms = duration.as_millis();

    // 获取状态码
    let status = response.status();

    // 获取当前时间
    let now: DateTime<Utc> = Utc::now();
    let timestamp = now.format("%d/%b/%Y:%H:%M:%S %z");

    // 记录请求日志，格式类似nginx
    info!(
        r#"{} - - [{}] "{} {} {:?}" {} {}ms "{}" "{}""#,
        client_ip,
        timestamp,
        method,
        uri,
        version,
        status.as_u16(),
        duration_ms,
        user_agent,
        get_referer(&response)
    );

    response
}

/// 获取Referer信息
fn get_referer(response: &Response) -> &str {
    response
        .headers()
        .get("referer")
        .and_then(|h| h.to_str().ok())
        .unwrap_or("-")
}